Skip to content

Clear the 22 red test files on main and add the edition 18 lineage entry - #7

Draft
Portll wants to merge 11 commits into
mainfrom
fix/red-ci-20261112
Draft

Portll wants to merge 11 commits into
mainfrom
fix/red-ci-20261112

Conversation

@Portll

@Portll Portll commented Nov 11, 2026 •

Copy link
Copy Markdown
Owner

CI on main has failed on every push since 2026-10-21. On f0ae536, Node 22 fails 39 tests in 22 files on ubuntu and 24 on macOS.

What changes

  • Tests pinned to one machine: timezone, hardware, APFS case-folding, the /private/var realpath, a macOS errno, installed semgrep and docker. Inputs are now injected or pinned. detectHardware gains an optional probe argument.
  • Gates that caught real drift: bin/disclosure-review.mjs uses lib/is-main.mjs and the monitor/lockfile.mjs writer; bin/commit-phase.mjs is back to 6 raw git calls; token-shaped literals in two unit tests are built at run time; the claude-spawn inventory, registry inventory and OPTIONAL_RECORDS are current; schema/wp-weakness-catalogue.schema.json is new.
  • Generated docs: docs/EXIT-CODES.md, docs/REFERENCE.md.
  • Edition 18: the lineage entry, byte-identical to private main 931d374d.
  • Live-tree writes: two unit tests no longer write .claude/store.
  • npm files: codegraph/ and chunk-diff/, which mcp/server.mjs and three admin/ modules import.

Decisions taken that the owner may reverse

  • bin/setup.mjs reads a zip pin in-process when tar cannot (GNU tar). Alternative: pin System32 tar on win32.
  • monitor/releases.example.json becomes a twelfth optional record. Alternative: a test exemption.
  • One raw git call in commit-phase.mjs goes through the file's git() wrapper. Alternative: raise the ceiling to 7.

Verified

Linux, Node 22.23: the 22 files plus five neighbouring files, 338 tests, 335 pass, 0 fail, 3 skip. Not run: the full suite, macOS, Windows, Node 26.

Not in this change

Three tests that fail on Node 26 only (daily-run.test.mjs:125,194, unit-memory-store-open-for-read.test.mjs:20) and docsite-og-image-entry.test.mjs:137 on macOS 26.

…ineage entry

Tests pinned to one machine (timezone, hardware, APFS case-folding, /private/var,
macOS errno, installed tools) now inject or pin their inputs. bin/disclosure-review.mjs
uses lib/is-main.mjs and monitor/lockfile.mjs. Two unit tests stop writing
.claude/store in the live tree. Inventories, docs/EXIT-CODES.md and docs/REFERENCE.md
are brought current. bin/setup.mjs reads a zip pin in-process when tar cannot.
package.json files gains codegraph/ and chunk-diff/, which mcp/ and admin/ import.
# Conflicts:
#	docs/EXIT-CODES.md
#	docs/REFERENCE.md
bin/test/no-argv-secrets.test.mjs read a secret written to a child's stdin
(lib/update/token.mjs, security -i) as shell interpolation because the
template sat on the same line as exec(. Stdin is the remedy the gate itself
names; spawn input payloads are now removed before matching, and a control
test proves the stdin form passes and the command-string form still fails.

monitor/mcp-tools-probe.mjs speak() wrote the three RPC frames with no stdin
error handler, so a server that exited before reading crashed the probe with
an unhandled EPIPE (CI ubuntu Node 22). EPIPE and ECONNRESET on stdin are now
expected; the exit handler gives the verdict. The race did not reproduce
locally: the new speak() test guards the exit verdict, not the race.
…s holding unread pipe data

On a refusal the helper SIGKILLs bwrap. If bwrap had not yet read the
resolv.conf written to fd 5, the helper's socketpair end failed with
ECONNRESET, which nothing handled: the helper crashed with exit 1 and a
stack, and a caller read the lane as failed instead of not run. This is the
intermittent bin/test/sandbox-netns-live.test.mjs:138 failure (1 !== 125)
seen on PRs #5 and #8. Pipe errors after a kill are now expected; any other
pipe error is a refusal. bin/test/sandbox-net-refusal-pipes.test.mjs
reproduces it with a fake bwrap that never reads fd 5: 0/15 before, 15/15
after.
…'s own shutdown deadlock skips instead of failing

The stress test's only control allocated objects, which never exercises the
background compile that deadlocks at natural exit (nodejs/node#54918, open).
macOS CI then failed intermittently on the renderer, which already exits
naturally and cannot exit more naturally than a control does. A second
control runs hot integer loops over a 1200x630x3 buffer and deflateSync at
level 9 with none of the renderer's code. If Node hangs either control, the
run skips and names the counts; process.exit() regressions are still caught
by the static exitHazards test on every run. Locally (Linux, 2 cores, Node
22.23) both controls hang: 13/24 and 17/24.
macOS Node 26 suite runs take 22-25 minutes; a run on 2026-11-12 was cancelled
at the 30-minute limit with every test it had reached passing.
@Portll
Portll force-pushed the fix/red-ci-20261112 branch from 6a4bc7c to 019f5c9 Compare November 12, 2026 03:56
…ode's own shutdown hang skips

Under --stress-concurrent-allocation Node can hang any process at natural
exit once it has run for a while (nodejs/node#54918, #64274, both open). On
4-core Linux, Node 22.23, a bare setTimeout(2 s) hung 5/24 and a 2 s busy loop
4/24; the old millisecond controls hung none, so they never met the condition
and the renderer's hangs were read as its own. The control now spins until its
CPU time equals one unstressed renderer run (about 100 ms), so 24 at once
stretch it as they stretch the renderer. Five runs: the control hung 1-9/24,
the renderer 7-13/24, so the run skips with the counts. Re-executing the
renderer with --single-threaded-gc was tried and dropped: the child never
hung, but the waiting parent did (7/24).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant